package com.zline.foodraise.util;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import android.content.ContentValues;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Environment;
import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.widget.Toast;

import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
import com.photoselector.util.CommonUtils;
import com.zline.foodraise.R;
import com.zline.foodraise.constant.Constant;

import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.RootContext;

/*
 * 图片工具类
 * 
 * */

@EBean
public class ImageUtil {
    private static final String LOG_TAG = ImageUtil.class.getSimpleName();
    @RootContext
    Context cxt;

    /*
     * 获取图片的缓存地址
     * SD 卡存在 SDCard/Android/data/你的应用包名/cache/目录
     * 不存在    /data/data/<application package>/cache/目录
     *
     * */
    public String getDiskCacheDir() {
        String cachePath = null;
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            cachePath = cxt.getExternalCacheDir().getPath();
        } else {
            cachePath = cxt.getCacheDir().getPath();
        }
        return cachePath;
    }

    public String getDiskFileDir(String dirName) {
        String filePath = null;
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            filePath = cxt.getExternalFilesDir(dirName).getPath();
        } else {
            filePath = cxt.getFilesDir().getPath() + "/" + Constant.SHARE;
        }
        return filePath;
    }


    public boolean saveBitmap(String filePath, String fileName, Bitmap bitmap) {
        File f = new File(filePath, fileName);
        FileOutputStream fOut = null;
        try {
            f.createNewFile();
            fOut = new FileOutputStream(f);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
            fOut.flush();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                fOut.close();
                LUtil.i(LOG_TAG, "save success");
                return true;
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        }
    }

    //通过decodeResourceStream 获得bitmap(decodeFile 不会缩放图片)
    public static Bitmap decodeResourceStream(Context context, String picPath) {
        File file = new File(picPath);
        Bitmap bitmap = null;
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(file);
            final TypedValue value = new TypedValue();
            value.density = DisplayMetrics.DENSITY_XHIGH;
            Resources resources = context.getResources();
            BitmapFactory.Options newOpts = new BitmapFactory.Options();
            newOpts.inSampleSize = 2;//设置采样率
            newOpts.inPurgeable = true;// 同时设置才会有效
            newOpts.inInputShareable = true;//。当系统内存不够时候图片自动被回收
            bitmap = BitmapFactory.decodeResourceStream(resources, value, inputStream, null, null);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) inputStream.close();
            } catch (IOException e) {

            }
        }
        return bitmap;
    }


    //获得本地图片的宽度
    public int getPicWidth(String picPath) {
        int width;
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        newOpts.inJustDecodeBounds = true;//只读边,不读内容
        Bitmap bitmap = BitmapFactory.decodeFile(picPath,newOpts);
        width = newOpts.outWidth;
        recycleBitmap(bitmap);
        return width;
    }

    //获得本地图片的宽度
    public int getPicHight(String picPath) {
        int height;
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        newOpts.inJustDecodeBounds = true;//只读边,不读内容
        Bitmap bitmap = BitmapFactory.decodeFile(picPath,newOpts);
        height = newOpts.outHeight;
        recycleBitmap(bitmap);
        return height;
    }


    //压缩图片质量并且存储（用于剪切后的图片处理）
    public void decodeAndCompressImageByQuality(String imagePath) {
        Bitmap bitmap = null;
        try {
            Uri uri = Uri.parse(imagePath);
            LUtil.i(LOG_TAG, "__________uri______" + imagePath);
            bitmap = BitmapFactory.decodeStream(cxt.getContentResolver().openInputStream(uri));
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int options = 100;
            bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//质量压缩方法，把压缩后的数据存放到baos中 (100表示不压缩，0表示压缩到最小)
            while (baos.toByteArray().length / 1024 > 100) {//循环判断如果压缩后图片是否大于100kb,大于继续压缩
                baos.reset();//重置baos即让下一次的写入覆盖之前的内容
                options -= 5;//图片质量每次减少5
                if (options < 0) options = 0;
                bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//将压缩后的图片保存到baos中
                if (options == 0) break;//如果图片的质量已降到最低则，不再进行压缩
            }
            FileOutputStream fos = new FileOutputStream(new File(imagePath));//将压缩后的图片保存的本地上指定路径中
            fos.write(baos.toByteArray());
            fos.flush();
            fos.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    /*
     压缩图片质量并且存储（用于剪切后的图片处理）
    * imageSize 图片大小
    * imagePath 图片本地地址
    *  */
    public Bitmap decodeAndCompressImageByQuality(String imagePath, int imageSize) {
        Bitmap bitmap = null;
        try {
            bitmap = BitmapFactory.decodeFile(imagePath);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int options = 100;
            bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//质量压缩方法，把压缩后的数据存放到baos中 (100表示不压缩，0表示压缩到最小)
            boolean isCompressed = false;
            while (baos.toByteArray().length / 1024 > imageSize) {//循环判断如果压缩后图片是否大于100kb,大于继续压缩
                baos.reset();//重置baos即让下一次的写入覆盖之前的内容
                options -= 5;//图片质量每次减少5
                if (options < 0) options = 0;
                bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//将压缩后的图片保存到baos中
                if (options == 0) break;//如果图片的质量已降到最低则，不再进行压缩
                isCompressed = true;
            }

            if (isCompressed) {
                bitmap = BitmapFactory.decodeByteArray(
                        baos.toByteArray(), 0, baos.toByteArray().length);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;
    }


    //获得图片的长宽比例
    public float getPicLengthWidthRatio(String imagePath) {
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        newOpts.inJustDecodeBounds = true;//只读边,不读内容
        Bitmap bitmap = null;
        float ratio = 1;
        try {
            bitmap = BitmapFactory.decodeFile(imagePath, newOpts);
            newOpts.inJustDecodeBounds = false;
            int width = newOpts.outWidth;
            int height = newOpts.outHeight;
            float max = Math.max(height, width);
            if (max == height) {
                ratio = max / width;
            } else {
                ratio = max / height;
            }
            recycleBitmap(bitmap);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return ratio;
    }


    //压缩图片质量并且存储（用于剪切后的图片处理）
    public void decodeAndCompressImageByQuality(Bitmap bitmap, String imagePath) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int options = 100;
            bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//质量压缩方法，把压缩后的数据存放到baos中 (100表示不压缩，0表示压缩到最小)
            while (baos.toByteArray().length / 1024 > 100) {//循环判断如果压缩后图片是否大于100kb,大于继续压缩
                baos.reset();//重置baos即让下一次的写入覆盖之前的内容
                options -= 5;//图片质量每次减少5
                if (options < 0) options = 0;
                bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//将压缩后的图片保存到baos中
                if (options == 0) break;//如果图片的质量已降到最低则，不再进行压缩
            }
            FileOutputStream fos = new FileOutputStream(new File(imagePath));//将压缩后的图片保存的本地上指定路径中
            fos.write(baos.toByteArray());
            fos.flush();
            fos.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    //像素压缩、然后进行质量压缩
    public void compressImageByPixel(String imagePath, String savePath) {
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        newOpts.inJustDecodeBounds = true;//只读边,不读内容
        Bitmap bitmap = null;
        try {
            bitmap = BitmapFactory.decodeFile(imagePath, newOpts);
            newOpts.inJustDecodeBounds = false;
            int width = newOpts.outWidth;
            int height = newOpts.outHeight;
            float maxSize = 1000f;//默认1000px
            int be = 1;
            if (width > height && width > maxSize) {//缩放比,用高或者宽其中较大的一个数据进行计算
                be = (int) (newOpts.outWidth / maxSize);
            } else if (width < height && height > maxSize) {
                be = (int) (newOpts.outHeight / maxSize);
            }
            LUtil.i(LOG_TAG, "__________Release_________" + be);
            be++;
            newOpts.inSampleSize = be;//设置采样率
            newOpts.inPreferredConfig = Bitmap.Config.RGB_565;//该模式是默认的,可不设
            newOpts.inPurgeable = true;// 同时设置才会有效
            newOpts.inInputShareable = true;//。当系统内存不够时候图片自动被回收
            bitmap = BitmapFactory.decodeFile(imagePath, newOpts);
            decodeAndCompressImageByQuality(bitmap, savePath);//压缩好比例大小后再进行质量压缩
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    //获取图片大小
    public long getPicSize(Uri uri) {
        Bitmap bitmap = null;
        try {
            bitmap = BitmapFactory.decodeStream(cxt.getContentResolver().openInputStream(uri));
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int options = 100;
            bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//质量压缩方法，把压缩后的数据存放到baos中 (100表示不压缩，0表示压缩到最小)
            return baos.toByteArray().length / 1024;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return 0;
    }

    //将bitmap 转化为字节
    public byte[] bitmap2Bytes(Bitmap bm) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
        return baos.toByteArray();
    }


    //回收bitmap
    public void recycleBitmap(Bitmap bitmap) {
        if (bitmap != null && !bitmap.isRecycled()) {
            bitmap.recycle();
            System.gc();
            bitmap = null;
        }
    }


    //图片加载框架，图片现实的基本配置
    public DisplayImageOptions getDisplayImageOptions(int loadImageRes,
                                                      int emptyUriImageRes, int onFailImageRes) {
        DisplayImageOptions options;
        options = new DisplayImageOptions.Builder()
                .showImageOnLoading(loadImageRes) //设置图片在下载期间显示的图片
                .showImageForEmptyUri(emptyUriImageRes)//设置图片Uri为空或是错误的时候显示的图片
                .showImageOnFail(onFailImageRes)  //设置图片加载/解码过程中错误时候显示的图片
                .cacheInMemory(true)//设置下载的图片是否缓存在内存中
                .cacheOnDisk(true)//设置下载的图片是否缓存在SD卡中
                .considerExifParams(true)  //是否考虑JPEG图像EXIF参数（旋转，翻转）
                .imageScaleType(ImageScaleType.EXACTLY)//设置图片以如何的编码方式显示
                .bitmapConfig(Bitmap.Config.RGB_565)//设置图片的解码类型//
                .displayer(new FadeInBitmapDisplayer(100))//是否图片加载好后渐入的动画时间
                .build();//构建完成
        return options;
    }


    //图片加载框架，图片现实的基本配置
    public DisplayImageOptions getDisplayImageOptions(int loadImageRes, int emptyUriImageRes,
                                                      int onFailImageRes,boolean diskCash) {
        DisplayImageOptions options;
        options = new DisplayImageOptions.Builder()
                .showImageOnLoading(loadImageRes) //设置图片在下载期间显示的图片
                .showImageForEmptyUri(emptyUriImageRes)//设置图片Uri为空或是错误的时候显示的图片
                .showImageOnFail(onFailImageRes)  //设置图片加载/解码过程中错误时候显示的图片
                .cacheInMemory(true)//设置下载的图片是否缓存在内存中
                .cacheOnDisk(diskCash)//设置下载的图片是否缓存在SD卡中
                .considerExifParams(true)  //是否考虑JPEG图像EXIF参数（旋转，翻转）
                .imageScaleType(ImageScaleType.EXACTLY)//设置图片以如何的编码方式显示
                .bitmapConfig(Bitmap.Config.RGB_565)//设置图片的解码类型//
                .displayer(new FadeInBitmapDisplayer(100))//是否图片加载好后渐入的动画时间
                .build();//构建完成
        return options;
    }


    //保存图片到系统相册中
    public String saveImageToGallery(Bitmap bmp) {
        String fileName = System.currentTimeMillis() + ".jpg";
        Uri uri;
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.DISPLAY_NAME, fileName);
        values.put(MediaStore.Images.Media.DESCRIPTION, fileName);
        values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        uri = cxt.getContentResolver().insert(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        OutputStream fOut = null;
        try {
            fOut = cxt.getContentResolver().openOutputStream(uri);
            bmp.compress(Bitmap.CompressFormat.JPEG, 100, fOut);

            fOut.flush();
            fOut.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            recycleBitmap(bmp);
        }
        String filePath = CommonUtils.query(cxt, uri);
        return filePath;
    }

    //图片旋转用于三星等特殊手机拍摄时候图片的旋转
    public void roateBitmap(Uri uri) {
        int rotate = 0;
        Bitmap bitmap = null;
        OutputStream fOut = null;
        try {
            String cameraCapturePath = CommonUtils.query(cxt, uri);
            ExifInterface exifInterface = new ExifInterface(cameraCapturePath);
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_270:
                    rotate = 270;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    rotate = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_90:
                    rotate = 90;
                    break;
            }
            if (rotate == 0) {//图片如果没有旋转直接退出
                return;
            }
            Matrix matrix = new Matrix();
            matrix.postRotate(rotate);
            //将长宽分别缩小一半
            BitmapFactory.Options newOpts = new BitmapFactory.Options();
            newOpts.inSampleSize = 2;//设置采样率
            newOpts.inPurgeable = true;// 同时设置才会有效
            newOpts.inInputShareable = true;//。当系统内存不够时候图片自动被回收
            bitmap = BitmapFactory.decodeFile(cameraCapturePath, newOpts);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
            fOut = cxt.getContentResolver().openOutputStream(uri);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
            fOut.flush();
            fOut.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            recycleBitmap(bitmap);
        }
    }

}
